home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / impacket / ImpactPacket.py < prev    next >
Text File  |  2006-05-23  |  55KB  |  1,819 lines

  1. # Copyright (c) 2003-2006 CORE Security Technologies
  2. #
  3. # This software is provided under under a slightly modified version
  4. # of the Apache Software License. See the accompanying LICENSE file
  5. # for more information.
  6. #
  7. # $Id: ImpactPacket.py,v 1.9 2006/05/23 22:25:34 gera Exp $
  8. #
  9. # Description:
  10. #  Network packet codecs basic building blocks.
  11. #  Low-level packet codecs for various Internet protocols.
  12. #
  13. # Author:
  14. #  Javier Burroni (javier)
  15. #  Bruce Leidl (brl)
  16. #  Javier Kohen (jkohen)
  17.  
  18. import array
  19. import struct
  20. import socket
  21. import string
  22. import sys
  23. from binascii import hexlify
  24.  
  25. """Classes to build network packets programmatically.
  26.  
  27. Each protocol layer is represented by an object, and these objects are
  28. hierarchically structured to form a packet. This list is traversable
  29. in both directions: from parent to child and vice versa.
  30.  
  31. All objects can be turned back into a raw buffer ready to be sent over
  32. the wire (see method get_packet).
  33. """
  34.  
  35. class ImpactPacketException:
  36.     def __init__(self, value):
  37.         self.value = value
  38.     def __str__(self):
  39.         return `self.value`
  40.  
  41. class PacketBuffer:
  42.     """Implement the basic operations utilized to operate on a
  43.     packet's raw buffer. All the packet classes derive from this one.
  44.  
  45.     The byte, word, long and ip_address getters and setters accept
  46.     negative indeces, having these the a similar effect as in a
  47.     regular Python sequence slice.
  48.     """
  49.  
  50.     def __init__(self, length = None):
  51.         "If 'length' is specified the buffer is created with an initial size"
  52.         if length:
  53.             self.__bytes = array.array('B', '\0' * length)
  54.         else:
  55.             self.__bytes = array.array('B')
  56.  
  57.     def set_bytes_from_string(self, data):
  58.         "Sets the value of the packet buffer from the string 'data'"
  59.         self.__bytes = array.array('B', data)
  60.  
  61.     def get_buffer_as_string(self):
  62.         "Returns the packet buffer as a string object"
  63.         return self.__bytes.tostring()
  64.  
  65.     def get_bytes(self):
  66.         "Returns the packet buffer as an array"
  67.         return self.__bytes
  68.  
  69.     def set_bytes(self, bytes):
  70.         "Set the packet buffer from an array"
  71.         # Make a copy to be safe
  72.         self.__bytes = array.array('B', bytes.tolist())
  73.  
  74.     def set_byte(self, index, value):
  75.         "Set byte at 'index' to 'value'"
  76.         index = self.__validate_index(index, 1)
  77.         self.__bytes[index] = value
  78.  
  79.     def get_byte(self, index):
  80.         "Return byte at 'index'"
  81.         index = self.__validate_index(index, 1)
  82.         return self.__bytes[index]
  83.  
  84.     def set_word(self, index, value, order = '!'):
  85.         "Set 2-byte word at 'index' to 'value'. See struct module's documentation to understand the meaning of 'order'."
  86.         index = self.__validate_index(index, 2)
  87.         ary = array.array("B", struct.pack(order + 'H', value))
  88.         if -2 == index:
  89.             self.__bytes[index:] = ary
  90.         else:
  91.             self.__bytes[index:index+2] = ary
  92.  
  93.     def get_word(self, index, order = '!'):
  94.         "Return 2-byte word at 'index'. See struct module's documentation to understand the meaning of 'order'."
  95.         index = self.__validate_index(index, 2)
  96.         if -2 == index:
  97.             bytes = self.__bytes[index:]
  98.         else:
  99.             bytes = self.__bytes[index:index+2]
  100.         (value,) = struct.unpack(order + 'H', bytes.tostring())
  101.         return value
  102.  
  103.     def set_long(self, index, value, order = '!'):
  104.         "Set 4-byte 'value' at 'index'. See struct module's documentation to understand the meaning of 'order'."
  105.         index = self.__validate_index(index, 4)
  106.         ary = array.array("B", struct.pack(order + 'L', value))
  107.         if -4 == index:
  108.             self.__bytes[index:] = ary
  109.         else:
  110.             self.__bytes[index:index+4] = ary
  111.  
  112.     def get_long(self, index, order = '!'):
  113.         "Return 4-byte value at 'index'. See struct module's documentation to understand the meaning of 'order'."
  114.         index = self.__validate_index(index, 4)
  115.         if -4 == index:
  116.             bytes = self.__bytes[index:]
  117.         else:
  118.             bytes = self.__bytes[index:index+4]
  119.         (value,) = struct.unpack(order + 'L', bytes.tostring())
  120.         return value
  121.  
  122.     def get_ip_address(self, index):
  123.         "Return 4-byte value at 'index' as an IP string"
  124.         index = self.__validate_index(index, 4)
  125.         if -4 == index:
  126.             bytes = self.__bytes[index:]
  127.         else:
  128.             bytes = self.__bytes[index:index+4]
  129.         return socket.inet_ntoa(bytes.tostring())
  130.  
  131.     def set_ip_address(self, index, ip_string):
  132.         "Set 4-byte value at 'index' from 'ip_string'"
  133.         index = self.__validate_index(index, 4)
  134.         raw = socket.inet_aton(ip_string)
  135.         (b1,b2,b3,b4) = struct.unpack("BBBB", raw)
  136.         self.set_byte(index, b1)
  137.         self.set_byte(index + 1, b2)
  138.         self.set_byte(index + 2, b3)
  139.         self.set_byte(index + 3, b4)
  140.  
  141.     def set_checksum_from_data(self, index, data):
  142.         "Set 16-bit checksum at 'index' by calculating checksum of 'data'"
  143.         self.set_word(index, self.compute_checksum(data))
  144.  
  145.     def compute_checksum(self, anArray):
  146.         "Return the one's complement of the one's complement sum of all the 16-bit words in 'anArray'"
  147.         nleft = len(anArray)
  148.         sum = 0
  149.         pos = 0
  150.         while nleft > 1:
  151.             sum = anArray[pos] * 256 + (anArray[pos + 1] + sum)
  152.             pos = pos + 2
  153.             nleft = nleft - 2
  154.         if nleft == 1:
  155.             sum = sum + anArray[pos] * 256
  156.         return self.normalize_checksum(sum)
  157.  
  158.     def normalize_checksum(self, aValue):
  159.         sum = aValue
  160.         sum = (sum >> 16) + (sum & 0xFFFF)
  161.         sum += (sum >> 16)
  162.         sum = (~sum & 0xFFFF)
  163.         return sum
  164.  
  165.     def __validate_index(self, index, size):
  166.         """This method performs two tasks: to allocate enough space to
  167.         fit the elements at positions index through index+size, and to
  168.         adjust negative indeces to their absolute equivalent.
  169.         """
  170.  
  171.         orig_index = index
  172.  
  173.         curlen = len(self.__bytes)
  174.         if index < 0:
  175.             index = curlen + index
  176.  
  177.         diff = index + size - curlen
  178.         if diff > 0:
  179.             self.__bytes.fromstring('\0' * diff)
  180.             if orig_index < 0:
  181.                 orig_index -= diff
  182.  
  183.         return orig_index
  184.  
  185.  
  186. class Header(PacketBuffer):
  187.     "This is the base class from which all protocol definitions extend."
  188.  
  189.     packet_printable = filter(lambda c: c not in string.whitespace, string.printable) + ' '
  190.  
  191.     ethertype = None
  192.     protocol = None
  193.     def __init__(self, length = None):
  194.         PacketBuffer.__init__(self, length)
  195.         self.__child = None
  196.         self.__parent = None
  197.         self.auto_checksum = 1
  198.  
  199.     def contains(self, aHeader):
  200.         "Set 'aHeader' as the child of this header"
  201.         self.__child = aHeader
  202.         aHeader.set_parent(self)
  203.  
  204.     def set_parent(self, my_parent):
  205.         "Set the header 'my_parent' as the parent of this header"
  206.         self.__parent = my_parent
  207.  
  208.     def child(self):
  209.         "Return the child of this header"
  210.         return self.__child
  211.  
  212.     def parent(self):
  213.         "Return the parent of this header"
  214.         return self.__parent
  215.  
  216.     def get_data_as_string(self):
  217.         "Returns all data from children of this header as string"
  218.  
  219.         if self.__child:
  220.             return self.__child.get_packet()
  221.         else:
  222.             return None
  223.  
  224.     def get_packet(self):
  225.         """Returns the raw representation of this packet and its
  226.         children as a string. The output from this method is a packet
  227.         ready to be transmited over the wire.
  228.         """
  229.         self.calculate_checksum()
  230.  
  231.         data = self.get_data_as_string()
  232.         if data:
  233.             return self.get_buffer_as_string() + data
  234.         else:
  235.             return self.get_buffer_as_string()
  236.  
  237.     def get_size(self):
  238.         "Return the size of this header and all of it's children"
  239.         tmp_value = self.get_header_size()
  240.         if self.child():
  241.             tmp_value = tmp_value + self.child().get_size()
  242.         return tmp_value
  243.  
  244.     def calculate_checksum(self):
  245.         "Calculate and set the checksum for this header"
  246.         pass
  247.  
  248.     def get_pseudo_header(self):
  249.         "Pseudo headers can be used to limit over what content will the checksums be calculated."
  250.         # default implementation returns empty array
  251.         return array.array('B')
  252.  
  253.     def load_header(self, aBuffer):
  254.         "Properly set the state of this instance to reflect that of the raw packet passed as argument."
  255.         self.set_bytes_from_string(aBuffer)
  256.         hdr_len = self.get_header_size()
  257.         if(len(aBuffer) < hdr_len):         #we must do something like this
  258.             diff = hdr_len - len(aBuffer)
  259.             for i in range(0, diff):
  260.                 aBuffer += '\x00'
  261.         self.set_bytes_from_string(aBuffer[:hdr_len])
  262.  
  263.     def get_header_size(self):
  264.         "Return the size of this header, that is, not counting neither the size of the children nor of the parents."
  265.         raise RuntimeError("Method %s.get_header_size must be overriden." % self.__class__)
  266.  
  267.     def list_as_hex(self, aList):
  268.         if len(aList):
  269.             ltmp = []
  270.             line = []
  271.             count = 0
  272.             for byte in aList:
  273.                 if not (count % 2):
  274.                     if (count % 16):
  275.                         ltmp.append(' ')
  276.                     else:
  277.                         ltmp.append(' '*4)
  278.                         ltmp.append(string.join(line, ''))
  279.                         ltmp.append('\n')
  280.                         line = []
  281.                 if chr(byte) in Header.packet_printable:
  282.                     line.append(chr(byte))
  283.                 else:
  284.                     line.append('.')
  285.                 ltmp.append('%.2x' % byte)
  286.                 count += 1
  287.             if (count%16):
  288.                 left = 16 - (count%16)
  289.                 ltmp.append(' ' * (4+(left / 2) + (left*2)))
  290.                 ltmp.append(string.join(line, ''))
  291.                 ltmp.append('\n')
  292.             return ltmp
  293.         else:
  294.             return []
  295.  
  296.     def __str__(self):
  297.         ltmp = self.list_as_hex(self.get_bytes().tolist())
  298.  
  299.         if self.__child:
  300.             ltmp.append(['\n', self.__child.__str__()])
  301.  
  302.         if len(ltmp)>0:
  303.             return string.join(ltmp, '')
  304.         else:
  305.             return ''
  306.  
  307.  
  308.  
  309. class Data(Header):
  310.     """This packet type can hold raw data. It's normally employed to
  311.     hold a packet's innermost layer's contents in those cases for
  312.     which the protocol details are unknown, and there's a copy of a
  313.     valid packet available.
  314.  
  315.     For instance, if all that's known about a certain protocol is that
  316.     a UDP packet with its contents set to "HELLO" initiate a new
  317.     session, creating such packet is as simple as in the following code
  318.     fragment:
  319.     packet = UDP()
  320.     packet.contains('HELLO')
  321.     """
  322.  
  323.     def __init__(self, aBuffer = None):
  324.         Header.__init__(self)
  325.         if aBuffer:
  326.            self.set_data(aBuffer)
  327.  
  328.     def set_data(self, data):
  329.         self.set_bytes_from_string(data)
  330.  
  331.     def get_size(self):
  332.         return len(self.get_bytes())
  333.  
  334.  
  335.  
  336. class Ethernet(Header):
  337.     def __init__(self, aBuffer = None):
  338.         Header.__init__(self, 14)
  339.         if(aBuffer):
  340.             self.load_header(aBuffer)
  341.  
  342.     def set_ether_type(self, aValue):
  343.         "Set ethernet data type field to 'aValue'"
  344.         self.set_word(12, aValue)
  345.  
  346.     def get_ether_type(self):
  347.         "Return ethernet data type field"
  348.         return self.get_word(12)
  349.  
  350.     def get_header_size(self):
  351.         "Return size of Ethernet header"
  352.         return 14
  353.  
  354.     def get_packet(self):
  355.  
  356.         if self.child():
  357.             self.set_ether_type(self.child().ethertype)
  358.         return Header.get_packet(self)
  359.  
  360.     def get_ether_dhost(self):
  361.         "Return 48 bit destination ethernet address as a 6 byte array"
  362.         return self.get_bytes()[0:6]
  363.  
  364.     def set_ether_dhost(self, aValue):
  365.         "Set destination ethernet address from 6 byte array 'aValue'"
  366.         for i in range(0, 6):
  367.             self.set_byte(i, aValue[i])
  368.  
  369.     def get_ether_shost(self):
  370.         "Return 48 bit source ethernet address as a 6 byte array"
  371.         return self.get_bytes()[6:12]
  372.  
  373.     def set_ether_shost(self, aValue):
  374.         "Set source ethernet address from 6 byte array 'aValue'"
  375.         for i in range(0, 6):
  376.             self.set_byte(i + 6, aValue[i])
  377.  
  378.     def as_eth_addr(self, anArray):
  379.         tmp_list = anArray.tolist()
  380.         if not tmp_list:
  381.             return ''
  382.         tmp_str = '%x' % tmp_list[0]
  383.         for i in range(1, len(tmp_list)):
  384.             tmp_str += ':%x' % tmp_list[i]
  385.         return tmp_str
  386.  
  387.     def __str__(self):
  388.         tmp_str = 'Ether: ' + self.as_eth_addr(self.get_ether_shost()) + ' -> '
  389.         tmp_str += self.as_eth_addr(self.get_ether_dhost())
  390.         if self.child():
  391.             tmp_str += '\n' + self.child().__str__()
  392.         return tmp_str
  393.  
  394.  
  395. # Linux "cooked" capture encapsulation.
  396. # Used, for instance, for packets returned by the "any" interface.
  397. class LinuxSLL(Header):
  398.     type_descriptions = [
  399.         "sent to us by somebody else",
  400.         "broadcast by somebody else",
  401.         "multicast by somebody else",
  402.         "sent to somebody else to somebody else",
  403.         "sent by us",
  404.         ]
  405.  
  406.     def __init__(self, aBuffer = None):
  407.         Header.__init__(self, 16)
  408.         if (aBuffer):
  409.             self.load_header(aBuffer)
  410.  
  411.     def set_type(self, type):
  412.         "Sets the packet type field to type"
  413.         self.set_word(0, type)
  414.  
  415.     def get_type(self):
  416.         "Returns the packet type field"
  417.         return self.get_word(0)
  418.  
  419.     def set_arphdr(self, value):
  420.         "Sets the ARPHDR value for the link layer device type"
  421.         self.set_word(2, type)
  422.  
  423.     def get_arphdr(self):
  424.         "Returns the ARPHDR value for the link layer device type"
  425.         return self.get_word(2)
  426.  
  427.     def set_addr_len(self, len):
  428.         "Sets the length of the sender's address field to len"
  429.         self.set_word(4, len)
  430.  
  431.     def get_addr_len(self):
  432.         "Returns the length of the sender's address field"
  433.         return self.get_word(4)
  434.  
  435.     def set_addr(self, addr):
  436.         "Sets the sender's address field to addr. Addr must be at most 8-byte long."
  437.         if (len(addr) < 8):
  438.             addr += '\0' * (8 - len(addr))
  439.         self.get_bytes()[6:14] = addr
  440.  
  441.     def get_addr(self):
  442.         "Returns the sender's address field"
  443.         return self.get_bytes()[6:14].tostring()
  444.  
  445.     def set_ether_type(self, aValue):
  446.         "Set ethernet data type field to 'aValue'"
  447.         self.set_word(14, aValue)
  448.  
  449.     def get_ether_type(self):
  450.         "Return ethernet data type field"
  451.         return self.get_word(14)
  452.  
  453.     def get_header_size(self):
  454.         "Return size of packet header"
  455.         return 16
  456.  
  457.     def get_packet(self):
  458.         if self.child():
  459.             self.set_ether_type(self.child().ethertype)
  460.         return Header.get_packet(self)
  461.  
  462.     def get_type_desc(self):
  463.         type = self.get_type()
  464.         if type < len(LinuxSLL.type_descriptions):
  465.             return LinuxSLL.type_descriptions[type]
  466.         else:
  467.             return "Unknown"
  468.  
  469.     def __str__(self):
  470.         ss = []
  471.         alen = self.get_addr_len()
  472.         addr = hexlify(self.get_addr()[0:alen])
  473.         ss.append("Linux SLL: addr=%s type=`%s'" % (addr, self.get_type_desc()))
  474.         if self.child():
  475.             ss.append(self.child().__str__())
  476.  
  477.         return '\n'.join(ss)
  478.  
  479.  
  480. class IP(Header):
  481.     ethertype = 0x800
  482.     def __init__(self, aBuffer = None):
  483.         Header.__init__(self, 20)
  484.         self.set_ip_v(4)
  485.         self.set_ip_hl(5)
  486.         self.set_ip_ttl(255)
  487.         self.__option_list = []
  488.         if(aBuffer):
  489.             self.load_header(aBuffer)
  490.         if sys.platform.count('bsd'):
  491.             self.is_BSD = True
  492.         else:
  493.             self.is_BSD = False
  494.  
  495.  
  496.     def get_packet(self):
  497.         # set protocol
  498.         if self.get_ip_p() == 0 and self.child():
  499.             self.set_ip_p(self.child().protocol)
  500.  
  501.         # set total length
  502.         if self.get_ip_len() == 0:
  503.             self.set_ip_len(self.get_size())
  504.  
  505.         child_data = self.get_data_as_string();
  506.  
  507.         my_bytes = self.get_bytes()
  508.  
  509.         for op in self.__option_list:
  510.             my_bytes.extend(op.get_bytes())
  511.  
  512.         # Pad to a multiple of 4 bytes
  513.         num_pad = (4 - (len(my_bytes) % 4)) % 4
  514.         if num_pad:
  515.             my_bytes.fromstring("\0"* num_pad)
  516.  
  517.         # only change ip_hl value if options are present
  518.         if len(self.__option_list):
  519.             self.set_ip_hl(len(my_bytes) / 4)
  520.  
  521.  
  522.         # set the checksum if the user hasn't modified it
  523.         if self.auto_checksum:
  524.             self.set_ip_sum(self.compute_checksum(my_bytes))
  525.  
  526.         if child_data == None:
  527.             return my_bytes.tostring()
  528.         else:
  529.             return my_bytes.tostring() + child_data
  530.  
  531.  
  532.  
  533.   #  def calculate_checksum(self, buffer = None):
  534.   #      tmp_value = self.get_ip_sum()
  535.   #      if self.auto_checksum and (not tmp_value):
  536.   #          if buffer:
  537.   #              tmp_bytes = buffer
  538.   #          else:
  539.   #              tmp_bytes = self.bytes[0:self.get_header_size()]
  540.   #
  541.   #          self.set_ip_sum(self.compute_checksum(tmp_bytes))
  542.  
  543.  
  544.     def get_pseudo_header(self):
  545.         pseudo_buf = array.array("B")
  546.         pseudo_buf.extend(self.get_bytes()[12:20])
  547.         pseudo_buf.fromlist([0])
  548.         pseudo_buf.extend(self.get_bytes()[9:10])
  549.         tmp_size = self.child().get_size()
  550.  
  551.         size_str = struct.pack("!H", tmp_size)
  552.  
  553.         pseudo_buf.fromstring(size_str)
  554.         return pseudo_buf
  555.  
  556.     def add_option(self, option):
  557.         self.__option_list.append(option)
  558.         sum = 0
  559.         for op in self.__option_list:
  560.             sum += op.get_len()
  561.         if sum > 40:
  562.             raise ImpactPacketException, "Options overflowed in IP packet with length: %d" % sum
  563.  
  564.  
  565.     def get_ip_v(self):
  566.         n = self.get_byte(0)
  567.         return (n >> 4)
  568.  
  569.     def set_ip_v(self, value):
  570.         n = self.get_byte(0)
  571.         version = value & 0xF
  572.         n = n & 0xF
  573.         n = n | (version << 4)
  574.         self.set_byte(0, n)
  575.  
  576.     def get_ip_hl(self):
  577.         n = self.get_byte(0)
  578.         return (n & 0xF)
  579.  
  580.     def set_ip_hl(self, value):
  581.         n = self.get_byte(0)
  582.         len = value & 0xF
  583.         n = n & 0xF0
  584.         n = (n | len)
  585.         self.set_byte(0, n)
  586.  
  587.     def get_ip_tos(self):
  588.         return self.get_byte(1)
  589.  
  590.     def set_ip_tos(self,value):
  591.         self.set_byte(1, value)
  592.  
  593.     def get_ip_len(self):
  594.         if self.is_BSD:
  595.             return self.get_word(2, order = '=')
  596.         else:
  597.             return self.get_word(2)
  598.  
  599.     def set_ip_len(self, value):
  600.         if self.is_BSD:
  601.             self.set_word(2, value, order = '=')
  602.         else:
  603.             self.set_word(2, value)
  604.  
  605.     def get_ip_id(self):
  606.         return self.get_word(4)
  607.     def set_ip_id(self, value):
  608.         return self.set_word(4, value)
  609.  
  610.     def get_ip_off(self):
  611.         if self.is_BSD:
  612.             return self.get_word(6, order = '=')
  613.         else:
  614.             return self.get_word(6)
  615.  
  616.     def set_ip_off(self, aValue):
  617.         if self.is_BSD:
  618.             self.set_word(6, aValue, order = '=')
  619.         else:
  620.             self.set_word(6, aValue)
  621.  
  622.     def get_ip_offmask(self):
  623.         return self.get_ip_off() & 0x1FFF
  624.  
  625.     def set_ip_offmask(self, aValue):
  626.         tmp_value = self.get_ip_off() & 0xD000
  627.         tmp_value |= aValue
  628.         self.set_ip_off(tmp_value)
  629.  
  630.     def get_ip_rf(self):
  631.         return self.get_ip_off() & 0x8000
  632.  
  633.     def set_ip_rf(self, aValue):
  634.         tmp_value = self.get_ip_off()
  635.         if aValue:
  636.             tmp_value |= 0x8000
  637.         else:
  638.             my_not = 0xFFFF ^ 0x8000
  639.             tmp_value &= my_not
  640.         self.set_ip_off(tmp_value)
  641.  
  642.     def get_ip_df(self):
  643.         return self.get_ip_off() & 0x4000
  644.  
  645.     def set_ip_df(self, aValue):
  646.         tmp_value = self.get_ip_off()
  647.         if aValue:
  648.             tmp_value |= 0x4000
  649.         else:
  650.             my_not = 0xFFFF ^ 0x4000
  651.             tmp_value &= my_not
  652.         self.set_ip_off(tmp_value)
  653.  
  654.     def get_ip_mf(self):
  655.         return self.get_ip_off() & 0x2000
  656.  
  657.     def set_ip_mf(self, aValue):
  658.         tmp_value = self.get_ip_off()
  659.         if aValue:
  660.             tmp_value |= 0x2000
  661.         else:
  662.             my_not = 0xFFFF ^ 0x2000
  663.             tmp_value &= my_not
  664.         self.set_ip_off(tmp_value)
  665.  
  666.  
  667.     def fragment_by_list(self, aList):
  668.         if self.child():
  669.             proto = self.child().protocol
  670.         else:
  671.             proto = 0
  672.  
  673.         child_data = self.get_data_as_string()
  674.         if not child_data:
  675.             return [self]
  676.  
  677.         ip_header_bytes = self.get_bytes()
  678.         current_offset = 0
  679.         fragment_list = []
  680.  
  681.         for frag_size in aList:
  682.             ip = IP()
  683.             ip.set_bytes(ip_header_bytes) # copy of original header
  684.             ip.set_ip_p(proto)
  685.  
  686.  
  687.             if frag_size % 8:   # round this fragment size up to next multiple of 8
  688.                 frag_size += 8 - (frag_size % 8)
  689.  
  690.  
  691.             ip.set_ip_offmask(current_offset / 8)
  692.             current_offset += frag_size
  693.  
  694.             data = Data(child_data[:frag_size])
  695.             child_data = child_data[frag_size:]
  696.  
  697.             ip.set_ip_len(20 + data.get_size())
  698.             ip.contains(data)
  699.  
  700.  
  701.             if child_data:
  702.  
  703.                 ip.set_ip_mf(1)
  704.  
  705.                 fragment_list.append(ip)
  706.             else: # no more data bytes left to add to fragments
  707.  
  708.                 ip.set_ip_mf(0)
  709.  
  710.                 fragment_list.append(ip)
  711.                 return fragment_list
  712.  
  713.         if child_data: # any remaining data?
  714.             # create a fragment containing all of the remaining child_data
  715.             ip = IP()
  716.             ip.set_bytes(ip_header_bytes)
  717.             ip.set_ip_offmask(current_offset)
  718.             ip.set_ip_len(20 + len(child_data))
  719.             data = Data(child_data)
  720.             ip.contains(data)
  721.             fragment_list.append(ip)
  722.  
  723.         return fragment_list
  724.  
  725.  
  726.     def fragment_by_size(self, aSize):
  727.         data_len = len(self.get_data_as_string())
  728.         num_frags = data_len / aSize
  729.  
  730.         if data_len % aSize:
  731.             num_frags += 1
  732.  
  733.         size_list = []
  734.         for i in range(0, num_frags):
  735.             size_list.append(aSize)
  736.         return self.fragment_by_list(size_list)
  737.  
  738.  
  739.     def get_ip_ttl(self):
  740.         return self.get_byte(8)
  741.     def set_ip_ttl(self, value):
  742.         self.set_byte(8, value)
  743.  
  744.     def get_ip_p(self):
  745.         return self.get_byte(9)
  746.  
  747.     def set_ip_p(self, value):
  748.         self.set_byte(9, value)
  749.  
  750.     def get_ip_sum(self):
  751.         return self.get_word(10)
  752.     def set_ip_sum(self, value):
  753.         self.auto_checksum = 0
  754.         self.set_word(10, value)
  755.  
  756.     def get_ip_src(self):
  757.         return self.get_ip_address(12)
  758.     def set_ip_src(self, value):
  759.         self.set_ip_address(12, value)
  760.  
  761.     def get_ip_dst(self):
  762.         return self.get_ip_address(16)
  763.  
  764.     def set_ip_dst(self, value):
  765.         self.set_ip_address(16, value)
  766.  
  767.     def get_header_size(self):
  768.         op_len = 0
  769.         for op in self.__option_list:
  770.             op_len += op.get_len()
  771.  
  772.         num_pad = (4 - (op_len % 4)) % 4
  773.  
  774.         return 20 + op_len + num_pad
  775.  
  776.     def load_header(self, aBuffer):
  777.         self.set_bytes_from_string(aBuffer[:20])
  778.         opt_left = (self.get_ip_hl() - 5) * 4
  779.         opt_bytes = array.array('B', aBuffer[20:(20 + opt_left)])
  780.         if len(opt_bytes) != opt_left:
  781.             raise ImpactPacketException, "Cannot load options from truncated packet"
  782.  
  783.  
  784.         while opt_left:
  785.             op_type = opt_bytes[0]
  786.             if op_type == IPOption.IPOPT_EOL or op_type == IPOption.IPOPT_NOP:
  787.                 new_option = IPOption(op_type)
  788.                 op_len = 1
  789.             else:
  790.                 op_len = opt_bytes[1]
  791.                 if op_len > len(opt_bytes):
  792.                     raise ImpactPacketException, "IP Option length is too high"
  793.  
  794.                 new_option = IPOption(op_type, op_len)
  795.                 new_option.set_bytes(opt_bytes[:op_len])
  796.  
  797.             opt_bytes = opt_bytes[op_len:]
  798.             opt_left -= op_len
  799.             self.add_option(new_option)
  800.             if op_type == IPOption.IPOPT_EOL:
  801.                 break
  802.  
  803.  
  804.     def __str__(self):
  805.         tmp_str = 'IP ' + self.get_ip_src() + ' -> ' + self.get_ip_dst()
  806.         for op in self.__option_list:
  807.             tmp_str += '\n' + op.__str__()
  808.         if self.child():
  809.             tmp_str += '\n' + self.child().__str__()
  810.         return tmp_str
  811.  
  812.  
  813. class IPOption(PacketBuffer):
  814.     IPOPT_EOL = 0
  815.     IPOPT_NOP = 1
  816.     IPOPT_RR = 7
  817.     IPOPT_TS = 68
  818.     IPOPT_LSRR = 131
  819.     IPOPT_SSRR = 137
  820.  
  821.     def __init__(self, opcode = 0, size = None):
  822.         if size and (size < 3 or size > 39):
  823.             raise ImpactPacketException, "IP Options must have a size between 3 and 39 bytes"
  824.  
  825.         if(opcode == IPOption.IPOPT_EOL):
  826.             PacketBuffer.__init__(self, 1)
  827.             self.set_code(IPOption.IPOPT_EOL)
  828.         elif(opcode == IPOption.IPOPT_NOP):
  829.             PacketBuffer.__init__(self, 1)
  830.             self.set_code(IPOption.IPOPT_NOP)
  831.         elif(opcode == IPOption.IPOPT_RR):
  832.             if not size:
  833.                 size = 39
  834.             PacketBuffer.__init__(self, size)
  835.             self.set_code(IPOption.IPOPT_RR)
  836.             self.set_len(size)
  837.             self.set_ptr(4)
  838.  
  839.         elif(opcode == IPOption.IPOPT_LSRR):
  840.             if not size:
  841.                 size = 39
  842.             PacketBuffer.__init__(self, size)
  843.             self.set_code(IPOption.IPOPT_LSRR)
  844.             self.set_len(size)
  845.             self.set_ptr(4)
  846.  
  847.         elif(opcode == IPOption.IPOPT_SSRR):
  848.             if not size:
  849.                 size = 39
  850.             PacketBuffer.__init__(self, size)
  851.             self.set_code(IPOption.IPOPT_SSRR)
  852.             self.set_len(size)
  853.             self.set_ptr(4)
  854.  
  855.         elif(opcode == IPOption.IPOPT_TS):
  856.             if not size:
  857.                 size = 40
  858.             PacketBuffer.__init__(self, size)
  859.             self.set_code(IPOption.IPOPT_TS)
  860.             self.set_len(size)
  861.             self.set_ptr(5)
  862.             self.set_flags(0)
  863.         else:
  864.             if not size:
  865.                 raise ImpactPacketError, "Size required for this type"
  866.             PacketBuffer.__init__(self,size)
  867.             self.set_code(opcode)
  868.             self.set_len(size)
  869.  
  870.  
  871.     def append_ip(self, ip):
  872.         op = self.get_code()
  873.         if not (op == IPOption.IPOPT_RR or op == IPOption.IPOPT_LSRR or op == IPOption.IPOPT_SSRR or op == IPOption.IPOPT_TS):
  874.             raise ImpactPacketException, "append_ip() not support for option type %d" % self.opt_type
  875.  
  876.         p = self.get_ptr()
  877.         if not p:
  878.             raise ImpactPacketException, "append_ip() failed, option ptr uninitialized"
  879.  
  880.         if (p + 4) > self.get_len():
  881.             raise ImpactPacketException, "append_ip() would overflow option"
  882.  
  883.         self.set_ip_address(p - 1, ip)
  884.         p += 4
  885.         self.set_ptr(p)
  886.  
  887.  
  888.     def set_code(self, value):
  889.         self.set_byte(0, value)
  890.  
  891.     def get_code(self):
  892.         return self.get_byte(0)
  893.  
  894.  
  895.     def set_flags(self, flags):
  896.         if not (self.get_code() == IPOption.IPOPT_TS):
  897.             raise ImpactPacketException, "Operation only supported on Timestamp option"
  898.         self.set_byte(3, flags)
  899.  
  900.     def get_flags(self, flags):
  901.         if not (self.get_code() == IPOption.IPOPT_TS):
  902.             raise ImpactPacketException, "Operation only supported on Timestamp option"
  903.         return self.get_byte(3)
  904.  
  905.  
  906.     def set_len(self, len):
  907.         self.set_byte(1, len)
  908.  
  909.  
  910.     def set_ptr(self, ptr):
  911.         self.set_byte(2, ptr)
  912.  
  913.     def get_ptr(self):
  914.         return self.get_byte(2)
  915.  
  916.     def get_len(self):
  917.         return len(self.get_bytes())
  918.  
  919.  
  920.     def __str__(self):
  921.         map = {IPOption.IPOPT_EOL : "End of List ",
  922.                IPOption.IPOPT_NOP : "No Operation ",
  923.                IPOption.IPOPT_RR  : "Record Route ",
  924.                IPOption.IPOPT_TS  : "Timestamp ",
  925.                IPOption.IPOPT_LSRR : "Loose Source Route ",
  926.                IPOption.IPOPT_SSRR : "Strict Source Route "}
  927.  
  928.         tmp_str = "\tIP Option: "
  929.         op = self.get_code()
  930.         if map.has_key(op):
  931.             tmp_str += map[op]
  932.         else:
  933.             tmp_str += "Code: %d " % op
  934.  
  935.         if op == IPOption.IPOPT_RR or op == IPOption.IPOPT_LSRR or op ==IPOption.IPOPT_SSRR:
  936.             tmp_str += self.print_addresses()
  937.  
  938.  
  939.         return tmp_str
  940.  
  941.  
  942.     def print_addresses(self):
  943.         p = 3
  944.         tmp_str = "["
  945.         if self.get_len() >= 7: # at least one complete IP address
  946.             while 1:
  947.                 if p + 1 == self.get_ptr():
  948.                     tmp_str += "#"
  949.                 tmp_str += self.get_ip_address(p)
  950.                 p += 4
  951.                 if p >= self.get_len():
  952.                     break
  953.                 else:
  954.                     tmp_str += ", "
  955.         tmp_str += "] "
  956.         if self.get_ptr() % 4: # ptr field should be a multiple of 4
  957.             tmp_str += "nonsense ptr field: %d " % self.get_ptr()
  958.         return tmp_str
  959.  
  960.  
  961. class UDP(Header):
  962.     protocol = 17
  963.     def __init__(self, aBuffer = None):
  964.         Header.__init__(self, 8)
  965.         if(aBuffer):
  966.             self.load_header(aBuffer)
  967.  
  968.     def get_uh_sport(self):
  969.         return self.get_word(0)
  970.     def set_uh_sport(self, value):
  971.         self.set_word(0, value)
  972.  
  973.     def get_uh_dport(self):
  974.         return self.get_word(2)
  975.     def set_uh_dport(self, value):
  976.         self.set_word(2, value)
  977.  
  978.     def get_uh_ulen(self):
  979.         return self.get_word(4)
  980.  
  981.     def set_uh_ulen(self, value):
  982.         self.set_word(4, value)
  983.  
  984.     def get_uh_sum(self):
  985.         return self.get_word(6)
  986.  
  987.     def set_uh_sum(self, value):
  988.         self.set_word(6, value)
  989.         self.auto_checksum = 0
  990.  
  991.     def calculate_checksum(self):
  992.         if self.auto_checksum and (not self.get_uh_sum()):
  993.             # if there isn't a parent to grab a pseudo-header from we'll assume the user knows what they're doing
  994.             # and won't meddle with the checksum or throw an exception
  995.             if not self.parent:
  996.                 return
  997.  
  998.             buffer = self.parent().get_pseudo_header()
  999.  
  1000.             buffer += self.get_bytes()
  1001.             data = self.get_data_as_string()
  1002.             if(data):
  1003.                 buffer.fromstring(data)
  1004.             self.set_uh_sum(self.compute_checksum(buffer))
  1005.  
  1006.     def get_header_size(self):
  1007.         return 8
  1008.  
  1009.     def __str__(self):
  1010.         tmp_str = 'UDP %d -> %d' % (self.get_uh_sport(), self.get_uh_dport())
  1011.         if self.child():
  1012.             tmp_str += '\n' + self.child().__str__()
  1013.         return tmp_str
  1014.  
  1015.     def get_packet(self):
  1016.         # set total length
  1017.         if(self.get_uh_ulen() == 0):
  1018.             self.set_uh_ulen(self.get_size())
  1019.         return Header.get_packet(self)
  1020.  
  1021. class TCP(Header):
  1022.     protocol = 6
  1023.     def __init__(self, aBuffer = None):
  1024.         Header.__init__(self, 20)
  1025.         self.set_th_off(5)
  1026.         self.__option_list = []
  1027.         if aBuffer:
  1028.             self.load_header(aBuffer)
  1029.  
  1030.     def add_option(self, option):
  1031.         self.__option_list.append(option)
  1032.  
  1033.         sum = 0
  1034.         for op in self.__option_list:
  1035.             sum += op.get_size()
  1036.  
  1037.         if sum > 40:
  1038.             raise ImpactPacketException, "Cannot add TCP option, would overflow option space"
  1039.  
  1040.     def get_options(self):
  1041.         return self.__option_list
  1042.  
  1043.     def swapSourceAndDestination(self):
  1044.         oldSource = self.get_th_sport()
  1045.         self.set_th_sport(self.get_th_dport())
  1046.         self.set_th_dport(oldSource)
  1047.  
  1048.     #
  1049.     # Header field accessors
  1050.     #
  1051.  
  1052.     def set_th_sport(self, aValue):
  1053.         self.set_word(0, aValue)
  1054.  
  1055.     def get_th_sport(self):
  1056.         return self.get_word(0)
  1057.  
  1058.     def get_th_dport(self):
  1059.         return self.get_word(2)
  1060.  
  1061.     def set_th_dport(self, aValue):
  1062.         self.set_word(2, aValue)
  1063.  
  1064.     def get_th_seq(self):
  1065.         return self.get_long(4)
  1066.  
  1067.     def set_th_seq(self, aValue):
  1068.         self.set_long(4, aValue)
  1069.  
  1070.     def get_th_ack(self):
  1071.         return self.get_long(8)
  1072.  
  1073.     def set_th_ack(self, aValue):
  1074.         self.set_long(8, aValue)
  1075.  
  1076.     def get_th_flags(self):
  1077.         return self.get_word(12)
  1078.  
  1079.     def set_th_flags(self, aValue):
  1080.         self.set_word(12, aValue)
  1081.  
  1082.     def get_th_win(self):
  1083.         return self.get_word(14)
  1084.  
  1085.     def set_th_win(self, aValue):
  1086.         self.set_word(14, aValue)
  1087.  
  1088.     def set_th_sum(self, aValue):
  1089.         self.set_word(16, aValue)
  1090.         self.auto_checksum = 0
  1091.  
  1092.     def get_th_sum(self):
  1093.         return self.get_long(16)
  1094.  
  1095.     def get_th_urp(self):
  1096.         return self.get_word(18)
  1097.  
  1098.     def set_th_urp(self, aValue):
  1099.         return self.set_word(18, aValue)
  1100.  
  1101.     # Flag accessors
  1102.  
  1103.     def get_th_off(self):
  1104.         tmp_value = self.get_th_flags() >> 12
  1105.         return tmp_value
  1106.  
  1107.     def set_th_off(self, aValue):
  1108.         self.reset_flags(0xF000)
  1109.         self.set_flags(aValue << 12)
  1110.  
  1111.     def get_CWR(self):
  1112.         return self.get_flag(128)
  1113.     def set_CWR(self):
  1114.         return self.set_flags(128)
  1115.     def reset_CWR(self):
  1116.         return self.reset_flags(128)
  1117.  
  1118.     def get_ECE(self):
  1119.         return self.get_flag(64)
  1120.     def set_ECE(self):
  1121.         return self.set_flags(64)
  1122.     def reset_ECE(self):
  1123.         return self.reset_flags(64)
  1124.  
  1125.     def get_URG(self):
  1126.         return self.get_flag(32)
  1127.     def set_URG(self):
  1128.         return self.set_flags(32)
  1129.     def reset_URG(self):
  1130.         return self.reset_flags(32)
  1131.  
  1132.     def get_ACK(self):
  1133.         return self.get_flag(16)
  1134.     def set_ACK(self):
  1135.         return self.set_flags(16)
  1136.     def reset_ACK(self):
  1137.         return self.reset_flags(16)
  1138.  
  1139.     def get_PSH(self):
  1140.         return self.get_flag(8)
  1141.     def set_PSH(self):
  1142.         return self.set_flags(8)
  1143.     def reset_PSH(self):
  1144.         return self.reset_flags(8)
  1145.  
  1146.     def get_RST(self):
  1147.         return self.get_flag(4)
  1148.     def set_RST(self):
  1149.         return self.set_flags(4)
  1150.     def reset_RST(self):
  1151.         return self.reset_flags(4)
  1152.  
  1153.     def get_SYN(self):
  1154.         return self.get_flag(2)
  1155.     def set_SYN(self):
  1156.         return self.set_flags(2)
  1157.     def reset_SYN(self):
  1158.         return self.reset_flags(2)
  1159.  
  1160.     def get_FIN(self):
  1161.         return self.get_flag(1)
  1162.     def set_FIN(self):
  1163.         return self.set_flags(1)
  1164.     def reset_FIN(self):
  1165.         return self.reset_flags(1)
  1166.  
  1167.     # Overriden Methods
  1168.  
  1169.     def get_header_size(self):
  1170.  
  1171.         return 20 + len(self.get_padded_options())
  1172.  
  1173.  
  1174.     def calculate_checksum(self):
  1175.         if not self.auto_checksum or not self.parent():
  1176.             return
  1177.  
  1178.         self.set_th_sum(0)
  1179.         buffer = self.parent().get_pseudo_header()
  1180.         buffer += self.get_bytes()
  1181.         buffer += self.get_padded_options()
  1182.  
  1183.         data = self.get_data_as_string()
  1184.         if(data):
  1185.             buffer.fromstring(data)
  1186.  
  1187.         res = self.compute_checksum(buffer)
  1188.  
  1189.         self.set_th_sum(self.compute_checksum(buffer))
  1190.  
  1191.  
  1192.     def get_packet(self):
  1193.         "Returns entire packet including child data as a string.  This is the function used to extract the final packet"
  1194.  
  1195.         # only change th_off value if options are present
  1196.         if len(self.__option_list):
  1197.             self.set_th_off(self.get_header_size() / 4)
  1198.  
  1199.         self.calculate_checksum()
  1200.  
  1201.         bytes = self.get_bytes() + self.get_padded_options()
  1202.         data = self.get_data_as_string()
  1203.  
  1204.         if data:
  1205.             return bytes.tostring() + data
  1206.         else:
  1207.             return bytes.tostring()
  1208.  
  1209.  
  1210.     def load_header(self, aBuffer):
  1211.         self.set_bytes_from_string(aBuffer[:20])
  1212.         opt_left = (self.get_th_off() - 5) * 4
  1213.         opt_bytes = array.array('B', aBuffer[20:(20 + opt_left)])
  1214.         if len(opt_bytes) != opt_left:
  1215.             raise ImpactPacketException, "Cannot load options from truncated packet"
  1216.  
  1217.         while opt_left:
  1218.             op_kind = opt_bytes[0]
  1219.             if op_kind == TCPOption.TCPOPT_EOL or op_kind == TCPOption.TCPOPT_NOP:
  1220.                 new_option = TCPOption(op_kind)
  1221.                 op_len = 1
  1222.             else:
  1223.                 op_len = opt_bytes[1]
  1224.                 if op_len > len(opt_bytes):
  1225.                     raise ImpactPacketException, "TCP Option length is too high"
  1226.  
  1227.                 new_option = TCPOption(op_kind)
  1228.                 new_option.set_bytes(opt_bytes[:op_len])
  1229.  
  1230.             opt_bytes = opt_bytes[op_len:]
  1231.             opt_left -= op_len
  1232.             self.add_option(new_option)
  1233.             if op_kind == TCPOption.TCPOPT_EOL:
  1234.                 break
  1235.  
  1236.  
  1237.  
  1238.  
  1239.     #
  1240.     # Private
  1241.     #
  1242.  
  1243.     def get_flag(self, bit):
  1244.         if self.get_th_flags() & bit:
  1245.             return 1
  1246.         else:
  1247.             return 0
  1248.  
  1249.     def reset_flags(self, aValue):
  1250.         tmp_value = self.get_th_flags() & (~aValue)
  1251.         return self.set_word(12, tmp_value)
  1252.  
  1253.  
  1254.     def set_flags(self, aValue):
  1255.         tmp_value =  self.get_th_flags() | aValue
  1256.         return self.set_word(12, tmp_value)
  1257.  
  1258.     def get_padded_options(self):
  1259.         "Return an array containing all options padded to a 4 byte boundry"
  1260.         op_buf = array.array('B')
  1261.         for op in self.__option_list:
  1262.             op_buf += op.get_bytes()
  1263.         num_pad = (4 - (len(op_buf) % 4)) % 4
  1264.         if num_pad:
  1265.             op_buf.fromstring("\0" * num_pad)
  1266.         return op_buf
  1267.  
  1268.     def __str__(self):
  1269.         tmp_str = 'TCP '
  1270.         if self.get_ACK():
  1271.             tmp_str += 'ack '
  1272.         if self.get_FIN():
  1273.             tmp_str += 'fin '
  1274.         if self.get_PSH():
  1275.             tmp_str += 'push '
  1276.         if self.get_RST():
  1277.             tmp_str += 'rst '
  1278.         if self.get_SYN():
  1279.             tmp_str += 'syn '
  1280.         if self.get_URG():
  1281.             tmp_str += 'urg '
  1282.         tmp_str += '%d -> %d' % (self.get_th_sport(), self.get_th_dport())
  1283.         for op in self.__option_list:
  1284.             tmp_str += '\n' + op.__str__()
  1285.  
  1286.         if self.child():
  1287.             tmp_str += '\n' + self.child().__str__()
  1288.         return tmp_str
  1289.  
  1290.  
  1291. class TCPOption(PacketBuffer):
  1292.     TCPOPT_EOL =             0
  1293.     TCPOPT_NOP  =            1
  1294.     TCPOPT_MAXSEG =          2
  1295.     TCPOPT_WINDOW  =         3
  1296.     TCPOPT_SACK_PERMITTED =  4
  1297.     TCPOPT_SACK         =    5
  1298.     TCPOPT_TIMESTAMP    =    8
  1299.     TCPOPT_SIGNATURE    =    19
  1300.  
  1301.  
  1302.     def __init__(self, kind, data = None):
  1303.  
  1304.         if kind == TCPOption.TCPOPT_EOL:
  1305.             PacketBuffer.__init__(self, 1)
  1306.             self.set_kind(TCPOption.TCPOPT_EOL)
  1307.         elif kind == TCPOption.TCPOPT_NOP:
  1308.             PacketBuffer.__init__(self, 1)
  1309.             self.set_kind(TCPOption.TCPOPT_NOP)
  1310.         elif kind == TCPOption.TCPOPT_MAXSEG:
  1311.             PacketBuffer.__init__(self, 4)
  1312.             self.set_kind(TCPOption.TCPOPT_MAXSEG)
  1313.             self.set_len(4)
  1314.             if data:
  1315.                 self.set_mss(data)
  1316.             else:
  1317.                 self.set_mss(512)
  1318.         elif kind == TCPOption.TCPOPT_WINDOW:
  1319.             PacketBuffer.__init__(self, 3)
  1320.             self.set_kind(TCPOption.TCPOPT_WINDOW)
  1321.             self.set_len(3)
  1322.             if data:
  1323.                 self.set_shift_cnt(data)
  1324.             else:
  1325.                 self.set_shift_cnt(0)
  1326.         elif kind == TCPOption.TCPOPT_TIMESTAMP:
  1327.             PacketBuffer.__init__(self, 10)
  1328.             self.set_kind(TCPOption.TCPOPT_TIMESTAMP)
  1329.             self.set_len(10)
  1330.             if data:
  1331.                 self.set_ts(data)
  1332.             else:
  1333.                 self.set_ts(0)
  1334.         elif kind == TCPOption.TCPOPT_SACK_PERMITTED:
  1335.             PacketBuffer.__init__(self, 2)
  1336.             self.set_kind(TCPOption.TCPOPT_SACK_PERMITTED)
  1337.             self.set_len(2)                
  1338.  
  1339.     def set_kind(self, kind):
  1340.         self.set_byte(0, kind)
  1341.  
  1342.  
  1343.     def get_kind(self):
  1344.         return self.get_byte(0)
  1345.  
  1346.  
  1347.     def set_len(self, len):
  1348.         if self.get_size() < 2:
  1349.             raise ImpactPacketException, "Cannot set length field on option of less than two bytes"
  1350.         self.set_byte(1, len)
  1351.  
  1352.     def get_len(self):
  1353.         if self.get_size() < 2:
  1354.             raise ImpactPacketException, "Cannot retrive length field from option of less that two bytes"
  1355.         return self.get_byte(1)
  1356.  
  1357.     def get_size(self):
  1358.         return len(self.get_bytes())
  1359.  
  1360.  
  1361.     def set_mss(self, len):
  1362.         if self.get_kind() != TCPOption.TCPOPT_MAXSEG:
  1363.             raise ImpactPacketException, "Can only set MSS on TCPOPT_MAXSEG option"
  1364.         self.set_word(2, len)
  1365.  
  1366.     def get_mss(self):
  1367.         if self.get_kind() != TCPOption.TCPOPT_MAXSEG:
  1368.             raise ImpactPacketException, "Can only retrieve MSS from TCPOPT_MAXSEG option"
  1369.         return self.get_word(2)
  1370.  
  1371.     def set_shift_cnt(self, cnt):
  1372.         if self.get_kind() != TCPOption.TCPOPT_WINDOW:
  1373.             raise ImpactPacketException, "Can only set Shift Count on TCPOPT_WINDOW option"
  1374.         self.set_byte(2, cnt)
  1375.  
  1376.     def get_shift_cnt(self):
  1377.         if self.get_kind() != TCPOption.TCPOPT_WINDOW:
  1378.             raise ImpactPacketException, "Can only retrieve Shift Count from TCPOPT_WINDOW option"
  1379.         return self.get_byte(2)
  1380.  
  1381.     def get_ts(self):
  1382.         if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP:
  1383.             raise ImpactPacketException, "Can only retrieve timestamp from TCPOPT_TIMESTAMP option"
  1384.         return self.get_long(2)
  1385.  
  1386.     def set_ts(self, ts):
  1387.         if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP:
  1388.             raise ImpactPacketException, "Can only set timestamp on TCPOPT_TIMESTAMP option"
  1389.         self.set_long(2, ts)
  1390.  
  1391.     def get_ts_echo(self):
  1392.         if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP:
  1393.             raise ImpactPacketException, "Can only retrieve timestamp from TCPOPT_TIMESTAMP option"
  1394.         self.get_long(6)
  1395.  
  1396.     def set_ts_echo(self, ts):
  1397.         if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP:
  1398.             raise ImpactPacketException, "Can only set timestamp on TCPOPT_TIMESTAMP option"
  1399.  
  1400.  
  1401.  
  1402.     def __str__(self):
  1403.         map = { TCPOption.TCPOPT_EOL : "End of List ",
  1404.                 TCPOption.TCPOPT_NOP : "No Operation ",
  1405.                 TCPOption.TCPOPT_MAXSEG : "Maximum Segment Size ",
  1406.                 TCPOption.TCPOPT_WINDOW : "Window Scale ",
  1407.                 TCPOption.TCPOPT_TIMESTAMP : "Timestamp " }
  1408.  
  1409.         tmp_str = "\tTCP Option: "
  1410.         op = self.get_kind()
  1411.         if map.has_key(op):
  1412.             tmp_str += map[op]
  1413.         else:
  1414.             tmp_str += " kind: %d " % op
  1415.         if op == TCPOption.TCPOPT_MAXSEG:
  1416.             tmp_str += " MSS : %d " % self.get_mss()
  1417.         elif op == TCPOption.TCPOPT_WINDOW:
  1418.             tmp_str += " Shift Count: %d " % self.get_shift_cnt()
  1419.         elif op == TCPOption.TCPOPT_TIMESTAMP:
  1420.             pass # TODO
  1421.         return tmp_str
  1422.  
  1423. class ICMP(Header):
  1424.     protocol = 1
  1425.     ICMP_ECHOREPLY              = 0
  1426.     ICMP_UNREACH                = 3
  1427.     ICMP_UNREACH_NET            = 0
  1428.     ICMP_UNREACH_HOST           = 1
  1429.     ICMP_UNREACH_PROTOCOL       = 2
  1430.     ICMP_UNREACH_PORT           = 3
  1431.     ICMP_UNREACH_NEEDFRAG       = 4
  1432.     ICMP_UNREACH_SRCFAIL        = 5
  1433.     ICMP_UNREACH_NET_UNKNOWN    = 6
  1434.     ICMP_UNREACH_HOST_UNKNOWN   = 7
  1435.     ICMP_UNREACH_ISOLATED       = 8
  1436.     ICMP_UNREACH_NET_PROHIB     = 9
  1437.     ICMP_UNREACH_HOST_PROHIB    = 10
  1438.     ICMP_UNREACH_TOSNET         = 11
  1439.     ICMP_UNREACH_TOSHOST        = 12
  1440.     ICMP_UNREACH_FILTERPROHIB   = 13
  1441.     ICMP_UNREACH_HOST_PRECEDENCE = 14
  1442.     ICMP_UNREACH_PRECEDENCE_CUTOFF = 15
  1443.     ICMP_SOURCEQUENCH               = 4
  1444.     ICMP_REDIRECT                   = 5
  1445.     ICMP_REDIRECT_NET           = 0
  1446.     ICMP_REDIRECT_HOST          = 1
  1447.     ICMP_REDIRECT_TOSNET        = 2
  1448.     ICMP_REDIRECT_TOSHOST       = 3
  1449.     ICMP_ALTHOSTADDR                = 6
  1450.     ICMP_ECHO                       = 8
  1451.     ICMP_ROUTERADVERT               = 9
  1452.     ICMP_ROUTERSOLICIT              = 10
  1453.     ICMP_TIMXCEED                   = 11
  1454.     ICMP_TIMXCEED_INTRANS       = 0
  1455.     ICMP_TIMXCEED_REASS         = 1
  1456.     ICMP_PARAMPROB                  = 12
  1457.     ICMP_PARAMPROB_ERRATPTR     = 0
  1458.     ICMP_PARAMPROB_OPTABSENT    = 1
  1459.     ICMP_PARAMPROB_LENGTH       = 2
  1460.     ICMP_TSTAMP                     = 13
  1461.     ICMP_TSTAMPREPLY                = 14
  1462.     ICMP_IREQ                       = 15
  1463.     ICMP_IREQREPLY                  = 16
  1464.     ICMP_MASKREQ                    = 17
  1465.     ICMP_MASKREPLY                  = 18
  1466.  
  1467.     def __init__(self, aBuffer = None):
  1468.         Header.__init__(self, 8)
  1469.         if aBuffer:
  1470.             self.load_header(aBuffer)
  1471.  
  1472.     def get_header_size(self):
  1473.         anamolies = { ICMP.ICMP_TSTAMP : 20, ICMP.ICMP_TSTAMPREPLY : 20, ICMP.ICMP_MASKREQ : 12, ICMP.ICMP_MASKREPLY : 12 }
  1474.         if anamolies.has_key(self.get_icmp_type()):
  1475.             return anamolies[self.get_icmp_type()]
  1476.         else:
  1477.             return 8
  1478.  
  1479.     def get_icmp_type(self):
  1480.         return self.get_byte(0)
  1481.  
  1482.     def set_icmp_type(self, aValue):
  1483.         self.set_byte(0, aValue)
  1484.  
  1485.     def get_icmp_code(self):
  1486.         return self.get_byte(1)
  1487.  
  1488.     def set_icmp_code(self, aValue):
  1489.         self.set_byte(1, aValue)
  1490.  
  1491.     def get_icmp_cksum(self):
  1492.         return self.get_word(2)
  1493.  
  1494.     def set_icmp_cksum(self, aValue):
  1495.         self.set_word(2, aValue)
  1496.         self.auto_checksum = 0
  1497.  
  1498.     def get_icmp_gwaddr(self):
  1499.         return self.get_ip_address(4)
  1500.  
  1501.     def set_icmp_gwaddr(self, ip):
  1502.         self.set_ip_adress(4, ip)
  1503.  
  1504.     def get_icmp_id(self):
  1505.         return self.get_word(4)
  1506.  
  1507.     def set_icmp_id(self, aValue):
  1508.         self.set_word(4, aValue)
  1509.  
  1510.     def get_icmp_seq(self):
  1511.         return self.get_word(6)
  1512.  
  1513.     def set_icmp_seq(self, aValue):
  1514.         self.set_word(6, aValue)
  1515.  
  1516.     def get_icmp_void(self):
  1517.         return self.get_long(4)
  1518.  
  1519.     def set_icmp_void(self, aValue):
  1520.         self.set_long(4, aValue)
  1521.  
  1522.  
  1523.     def get_icmp_nextmtu(self):
  1524.         return self.get_word(6)
  1525.  
  1526.     def set_icmp_nextmtu(self, aValue):
  1527.         self.set_word(6, aValue)
  1528.  
  1529.     def get_icmp_num_addrs(self):
  1530.         return self.get_byte(4)
  1531.  
  1532.     def set_icmp_num_addrs(self, aValue):
  1533.         self.set_byte(4, aValue)
  1534.  
  1535.     def get_icmp_wpa(self):
  1536.         return self.get_byte(5)
  1537.  
  1538.     def set_icmp_wpa(self, aValue):
  1539.         self.set_byte(5, aValue)
  1540.  
  1541.     def get_icmp_lifetime(self):
  1542.         return self.get_word(6)
  1543.  
  1544.     def set_icmp_lifetime(self, aValue):
  1545.         self.set_word(6, aValue)
  1546.  
  1547.     def get_icmp_otime(self):
  1548.         return self.get_long(8)
  1549.  
  1550.     def set_icmp_otime(self, aValue):
  1551.         self.set_long(8, aValue)
  1552.  
  1553.     def get_icmp_rtime(self):
  1554.         return self.get_long(12)
  1555.  
  1556.     def set_icmp_rtime(self, aValue):
  1557.         self.set_long(12, aValue)
  1558.  
  1559.     def get_icmp_ttime(self):
  1560.         return self.get_long(16)
  1561.  
  1562.     def set_icmp_ttime(self, aValue):
  1563.         self.set_long(16, aValue)
  1564.  
  1565.     def get_icmp_mask(self):
  1566.         return self.get_ip_address(8)
  1567.  
  1568.     def set_icmp_mask(self, mask):
  1569.         self.set_ip_address(8, mask)
  1570.  
  1571.  
  1572.     def calculate_checksum(self):
  1573.         if self.auto_checksum and (not self.get_icmp_cksum()):
  1574.             buffer = self.get_buffer_as_string()
  1575.             data = self.get_data_as_string()
  1576.             if data:
  1577.                 buffer += data
  1578.  
  1579.             tmp_array = array.array('B', buffer)
  1580.             self.set_icmp_cksum(self.compute_checksum(tmp_array))
  1581.  
  1582.     def get_type_name(self, aType):
  1583.         tmp_type = {0:'ECHOREPLY', 3:'UNREACH', 4:'SOURCEQUENCH',5:'REDIRECT', 6:'ALTHOSTADDR', 8:'ECHO', 9:'ROUTERADVERT', 10:'ROUTERSOLICIT', 11:'TIMXCEED', 12:'PARAMPROB', 13:'TSTAMP', 14:'TSTAMPREPLY', 15:'IREQ', 16:'IREQREPLY', 17:'MASKREQ', 18:'MASKREPLY', 30:'TRACEROUTE', 31:'DATACONVERR', 32:'MOBILE REDIRECT', 33:'IPV6 WHEREAREYOU', 34:'IPV6 IAMHERE', 35:'MOBILE REGREQUEST', 36:'MOBILE REGREPLY', 39:'SKIP', 40:'PHOTURIS'}
  1584.         answer = tmp_type.get(aType, 'UNKNOWN')
  1585.         return answer
  1586.  
  1587.     def get_code_name(self, aType, aCode):
  1588.         tmp_code = {3:['UNREACH NET', 'UNREACH HOST', 'UNREACH PROTOCOL', 'UNREACH PORT', 'UNREACH NEEDFRAG', 'UNREACH SRCFAIL', 'UNREACH NET UNKNOWN', 'UNREACH HOST UNKNOWN', 'UNREACH ISOLATED', 'UNREACH NET PROHIB', 'UNREACH HOST PROHIB', 'UNREACH TOSNET', 'UNREACH TOSHOST', 'UNREACH FILTER PROHIB', 'UNREACH HOST PRECEDENCE', 'UNREACH PRECEDENCE CUTOFF', 'UNKNOWN ICMP UNREACH']}
  1589.         tmp_code[5] = ['REDIRECT NET', 'REDIRECT HOST', 'REDIRECT TOSNET', 'REDIRECT TOSHOST']
  1590.         tmp_code[9] = ['ROUTERADVERT NORMAL', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,'ROUTERADVERT NOROUTE COMMON']
  1591.         tmp_code[11] = ['TIMXCEED INTRANS ', 'TIMXCEED REASS']
  1592.         tmp_code[12] = ['PARAMPROB ERRATPTR ', 'PARAMPROB OPTABSENT', 'PARAMPROB LENGTH']
  1593.         tmp_code[40] = [None, 'PHOTURIS UNKNOWN INDEX', 'PHOTURIS AUTH FAILED', 'PHOTURIS DECRYPT FAILED']
  1594.         if tmp_code.has_key(aType):
  1595.             tmp_list = tmp_code[aType]
  1596.             if ((aCode + 1) > len(tmp_list)) or (not tmp_list[aCode]):
  1597.                 return 'UNKNOWN'
  1598.             else:
  1599.                 return tmp_list[aCode]
  1600.         else:
  1601.             return 'UNKNOWN'
  1602.  
  1603.     def __str__(self):
  1604.         tmp_type = self.get_icmp_type()
  1605.         tmp_code = self.get_icmp_code()
  1606.         tmp_str = 'ICMP type: ' + self.get_type_name(tmp_type)
  1607.         tmp_str+= ' code: ' + self.get_code_name(tmp_type, tmp_code)
  1608.         if self.child():
  1609.             tmp_str += '\n' + self.child().__str__()
  1610.         return tmp_str
  1611.  
  1612.     def isDestinationUnreachable(self):
  1613.         return self.get_icmp_type() == 3
  1614.  
  1615.     def isError(self):
  1616.         return not self.isQuery()
  1617.  
  1618.     def isHostUnreachable(self):
  1619.         return self.isDestinationUnreachable() and (self.get_icmp_code() == 1)
  1620.  
  1621.     def isNetUnreachable(self):
  1622.         return self.isDestinationUnreachable() and (self.get_icmp_code() == 0)
  1623.  
  1624.     def isPortUnreachable(self):
  1625.         return self.isDestinationUnreachable() and (self.get_icmp_code() == 3)
  1626.  
  1627.     def isProtocolUnreachable(self):
  1628.         return self.isDestinationUnreachable() and (self.get_icmp_code() == 2)
  1629.  
  1630.     def isQuery(self):
  1631.          tmp_dict = {8:'',  9:'',  10:'', 13:'', 14:'', 15:'', 16:'', 17:'', 18:''}
  1632.          return tmp_dict.has_key(self.get_icmp_type())
  1633.  
  1634. class IGMP(Header):
  1635.     protocol = 2
  1636.     def __init__(self, aBuffer = None):
  1637.         Header.__init__(self, 8)
  1638.         if aBuffer:
  1639.             self.load_header(aBuffer)
  1640.  
  1641.     def get_igmp_type(self):
  1642.         return self.get_byte(0)
  1643.  
  1644.     def set_igmp_type(self, aValue):
  1645.         self.set_byte(0, aValue)
  1646.  
  1647.     def get_igmp_code(self):
  1648.         return self.get_byte(1)
  1649.  
  1650.     def set_igmp_code(self, aValue):
  1651.         self.set_byte(1, aValue)
  1652.  
  1653.     def get_igmp_cksum(self):
  1654.         return self.get_word(2)
  1655.  
  1656.     def set_igmp_cksum(self, aValue):
  1657.         self.set_word(2, aValue)
  1658.  
  1659.     def get_igmp_group(self):
  1660.         return self.get_long(4)
  1661.  
  1662.     def set_igmp_group(self, aValue):
  1663.         self.set_long(4, aValue)
  1664.  
  1665.     def get_header_size(self):
  1666.         return 8
  1667.  
  1668.     def get_type_name(self, aType):
  1669.         tmp_dict = {0x11:'HOST MEMBERSHIP QUERY ', 0x12:'v1 HOST MEMBERSHIP REPORT ', 0x13:'IGMP DVMRP ', 0x14:' PIM ', 0x16:'v2 HOST MEMBERSHIP REPORT ', 0x17:'HOST LEAVE MESSAGE ', 0x1e:'MTRACE REPLY ', 0X1f:'MTRACE QUERY '}
  1670.         answer = tmp_type.get(aType, 'UNKNOWN TYPE OR VERSION ')
  1671.         return answer
  1672.  
  1673.     def calculate_checksum(self):
  1674.         if self.__auto_checksum and (not self.get_igmp_cksum()):
  1675.             self.set_igmp_cksum(self.compute_checksum(self.get_buffer_as_string()))
  1676.  
  1677.     def __str__(self):
  1678.         knowcode = 0
  1679.         tmp_str = 'IGMP: ' + self.get_type_name(self.get_igmp_type())
  1680.         tmp_str += 'Group: ' +  socket.inet_ntoa(pack('!L',self.get_igmp_group()))
  1681.         if self.child():
  1682.             tmp_str += '\n' + self.child().__str__()
  1683.         return tmp_str
  1684.  
  1685.  
  1686.  
  1687. class ARP(Header):
  1688.     ethertype = 0x806
  1689.     def __init__(self, aBuffer = None):
  1690.         Header.__init__(self, 7)
  1691.         if aBuffer:
  1692.             self.load_header(aBuffer)
  1693.  
  1694.     def get_ar_hrd(self):
  1695.         return self.get_word(0)
  1696.  
  1697.     def set_ar_hrd(self, aValue):
  1698.         self.set_word(0, aValue)
  1699.  
  1700.     def get_ar_pro(self):
  1701.         return self.get_word(2)
  1702.  
  1703.     def set_ar_pro(self, aValue):
  1704.         self.set_word(2, aValue)
  1705.  
  1706.     def get_ar_hln(self):
  1707.         return self.get_byte(4)
  1708.  
  1709.     def set_ar_hln(self, aValue):
  1710.         self.set_byte(4, aValue)
  1711.  
  1712.     def get_ar_pln(self):
  1713.         return self.get_byte(5)
  1714.  
  1715.     def set_ar_pln(self, aValue):
  1716.         self.set_byte(5, aValue)
  1717.  
  1718.     def get_ar_op(self):
  1719.         return self.get_word(6)
  1720.  
  1721.     def set_ar_op(self, aValue):
  1722.         self.set_word(6, aValue)
  1723.  
  1724.     def get_ar_sha(self):
  1725.         tmp_size = self.get_ar_hln()
  1726.         return self.get_bytes().tolist()[8: 8 + tmp_size]
  1727.  
  1728.     def set_ar_sha(self, aValue):
  1729.         for i in range(0, self.get_ar_hln()):
  1730.             self.set_byte(i + 8, aValue[i])
  1731.  
  1732.     def get_ar_spa(self):
  1733.         tmp_size = self.get_ar_pln()
  1734.         return self.get_bytes().tolist()[8 + self.get_ar_hln(): 8 + self.get_ar_hln() + tmp_size]
  1735.  
  1736.     def set_ar_spa(self, aValue):
  1737.         for i in range(0, self.get_ar_pln()):
  1738.             self.set_byte(i + 8 + self.get_ar_hln(), aValue[i])
  1739.  
  1740.     def get_ar_tha(self):
  1741.         tmp_size = self.get_ar_hln()
  1742.         tmp_from = 8 + self.get_ar_hln() + self.get_ar_pln()
  1743.         return self.get_bytes().tolist()[tmp_from: tmp_from + tmp_size]
  1744.  
  1745.     def set_ar_tha(self, aValue):
  1746.         tmp_from = 8 + self.get_ar_hln() + self.get_ar_pln()
  1747.         for i in range(0, self.get_ar_hln()):
  1748.             self.set_byte(i + tmp_from, aValue[i])
  1749.  
  1750.     def get_ar_tpa(self):
  1751.         tmp_size = self.get_ar_pln()
  1752.         tmp_from = 8 + ( 2 * self.get_ar_hln()) + self.get_ar_pln()
  1753.         return self.get_bytes().tolist()[tmp_from: tmp_from + tmp_size]
  1754.  
  1755.     def set_ar_tpa(self, aValue):
  1756.         tmp_from = 8 + (2 * self.get_ar_hln()) + self.get_ar_pln()
  1757.         for i in range(0, self.get_ar_pln()):
  1758.             self.set_byte(i + tmp_from, aValue[i])
  1759.  
  1760.     def get_header_size(self):
  1761.         return 8 + (2 * self.get_ar_hln()) + (2 * self.get_ar_pln())
  1762.  
  1763.     def get_op_name(self, ar_op):
  1764.         tmp_dict = {1:'REQUEST', 2:'REPLY', 3:'REVREQUEST', 4:'REVREPLY', 8:'INVREQUEST', 9:'INVREPLY'}
  1765.         answer = tmp_dict.get(ar_op, 'UNKNOWN')
  1766.         return answer
  1767.  
  1768.     def get_hrd_name(self, ar_hrd):
  1769.         tmp_dict = { 1:'ARPHRD ETHER', 6:'ARPHRD IEEE802', 15:'ARPHRD FRELAY'}
  1770.         answer = tmp_dict.get(ar_hrd, 'UNKNOWN')
  1771.         return answer
  1772.  
  1773.  
  1774.     def as_hrd(self, anArray):
  1775.         if not anArray:
  1776.             return ''
  1777.         tmp_str = '%x' % anArray[0]
  1778.         for i in range(1, len(anArray)):
  1779.             tmp_str += ':%x' % anArray[i]
  1780.         return tmp_str
  1781.  
  1782.     def as_pro(self, anArray):
  1783.         if not anArray:
  1784.             return ''
  1785.         tmp_str = '%d' % anArray[0]
  1786.         for i in range(1, len(anArray)):
  1787.             tmp_str += '.%d' % anArray[i]
  1788.         return tmp_str
  1789.  
  1790.     def __str__(self):
  1791.         tmp_op = self.get_ar_op()
  1792.         tmp_str = 'ARP format: ' + self.get_hrd_name(self.get_ar_hrd()) + ' '
  1793.         tmp_str += 'opcode: ' + self.get_op_name(tmp_op)
  1794.         tmp_str += '\n' + self.as_hrd(self.get_ar_sha()) + ' -> '
  1795.         tmp_str += self.as_hrd(self.get_ar_tha())
  1796.         tmp_str += '\n' + self.as_pro(self.get_ar_spa()) + ' -> '
  1797.         tmp_str += self.as_pro(self.get_ar_tpa())
  1798.         if self.child():
  1799.             tmp_str += '\n' + self.child().__str__()
  1800.         return tmp_str
  1801.  
  1802.  
  1803. def example(): #To execute an example, remove this line
  1804.     a = Ethernet()
  1805.     b = ARP()
  1806.     c = Data('Hola loco!!!')
  1807.     b.set_ar_hln(6)
  1808.     b.set_ar_pln(4)
  1809.     #a.set_ip_dst('192.168.22.6')
  1810.     #a.set_ip_src('1.1.1.2')
  1811.     a.contains(b)
  1812.     b.contains(c)
  1813.     b.set_ar_op(2)
  1814.     b.set_ar_hrd(1)
  1815.     b.set_ar_spa((192, 168, 22, 6))
  1816.     b.set_ar_tpa((192, 168, 66, 171))
  1817.     a.set_ether_shost((0x0, 0xe0, 0x7d, 0x8a, 0xef, 0x3d))
  1818.     a.set_ether_dhost((0x0, 0xc0, 0xdf, 0x6, 0x5, 0xe))
  1819.